package com.fowo.api.sys.service.impl;

import com.fowo.api.common.model.RException;
import com.fowo.api.sys.service.SysMailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Service
public class SysMailServiceImpl implements SysMailService {
    @Resource
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String fromUsername;

    @Resource
    private SpringTemplateEngine mailTemplateEngine;

    @Override
    public void send(String toMailAddress, String subject, String template, Map<String,Object> variables) throws MessagingException {

        String[] toAddress = toMailAddress.split("[,;]");
        // 解析主题 SpEL
        SpelExpressionParser subjectParser = new SpelExpressionParser();
        Expression expression = subjectParser.parseExpression(subject);
        EvaluationContext context = new StandardEvaluationContext();
        if (variables != null) {
            for(Map.Entry<String, Object> entry : variables.entrySet()) {
                context.setVariable(entry.getKey(), entry.getValue());
            }
        }
        String finalSubject = (String) expression.getValue(context);

        // 取邮件模版
        String mailBody = fillTemplate(template, variables);

        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setTo(toAddress);
        helper.setSubject(finalSubject);
        helper.setText(mailBody, true);
        message.setFrom(fromUsername);
        mailSender.send(message);
    }

    private String fillTemplate(String template, Map<String,Object> variables) {
        String templateResource = String.format("mail/templates/%s", template);
        InputStream resourceStream = SysMailServiceImpl.class.getClassLoader().getResourceAsStream(templateResource);
        if (resourceStream == null) {
            throw new RException(String.format("未找到指定的邮件横版 %s", template));
        }

        try {
            String templateBody = StreamUtils.copyToString(resourceStream, StandardCharsets.UTF_8);
            Context templateContext = new Context();
            templateContext.setVariables(variables);
            return mailTemplateEngine.process(templateBody, templateContext);
        } catch (IOException e) {
            throw new RuntimeException("读取模版文本时出现 IO 错误", e);
        }
    }
}
